//
//  DrawingView.m
//  TabulaImaginarius2
//
//  Created by TA2 on 5/3/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "DrawingView.h"

@implementation DrawingView

@synthesize map;
@synthesize scale;
@synthesize tileSize;
@synthesize drawingColor;
@synthesize currentPoint;
@synthesize snapToGrid;
@synthesize currentLayerIndex;

+ (Class)layerClass {
	return [CATiledLayer class];
}

- (id)initWithMap:(Map *)newMap withTileSize:(CGSize)size withScale:(int)scale {
    if ((self = [super initWithFrame:CGRectMake(0, 0, newMap.size.width, newMap.size.height)])) {
        self.map = newMap;
		self.multipleTouchEnabled = YES;
        CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
		tiledLayer.tileSize = size;
        
        /*tiledLayer.levelsOfDetail = 3;
		tiledLayer.levelsOfDetailBias = 0;
		if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
			tiledLayer.levelsOfDetail = 3;
			tiledLayer.levelsOfDetailBias = 2;
		}*/
        
		self.scale = scale;
		tileSize = (CGSize){tiledLayer.tileSize.width/self.scale, tiledLayer.tileSize.height/self.scale};
    }
	self.backgroundColor = [UIColor clearColor];
	self.currentLayerIndex = 0;
	self.drawingColor = [UIColor blackColor];
	self.snapToGrid = NO;
    return self;
}

- (void)dealloc {
    [map release];
    map = nil;
    [drawingColor release];
    drawingColor = nil;
    [super dealloc];
}

- (void)drawRect:(CGRect)rect {
    // get the scale from the context by getting the current transform matrix, then asking for
    // its "a" component, which is one of the two scale components. We could also ask for "d".
    // This assumes (safely) that the view is being scaled equally in both dimensions.
    //scale = CGContextGetCTM(context).a;
    //CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
    //tileSize = tiledLayer.tileSize;
    
    // Even at scales lower than 100%, we are drawing into a rect in the coordinate system of the full
    // image. One tile at 50% covers the width (in original image coordinates) of two tiles at 100%. 
    // So at 50% we need to stretch our tiles to double the width and height; at 25% we need to stretch 
    // them to quadruple the width and height; and so on.
    // (Note that this means that we are drawing very blurry images as the scale gets low. At 12.5%, 
    // our lowest scale, we are stretching about 6 small tiles to fill the entire original image area. 
    // But this is okay, because the big blurry image we're drawing here will be scaled way down before 
    // it is displayed.)
    //tileSize.width /= scale;
    //tileSize.height /= scale;
	
    // calculate the rows and columns of tiles that intersect the rect we have been asked to draw
    int firstCol = floorf(CGRectGetMinX(rect) / tileSize.width);
    int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize.width);
    int firstRow = floorf(CGRectGetMinY(rect) / tileSize.height);
    int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize.height);
	
    for (int row = firstRow; row <= lastRow; row++) {
        for (int col = firstCol; col <= lastCol; col++) {
			CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
                                         tileSize.width, tileSize.height);
			tileRect = CGRectIntersection(self.bounds, tileRect);
			CGLayerRef tile = [map drawingTileForPoint:CGPointMake(col, row) withTileSize:tileSize];
			if (tile) {
				CGContextDrawLayerInRect(UIGraphicsGetCurrentContext(), tileRect, tile);
			}
        }
    }
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch *touch = [touches anyObject];
	if (snapToGrid) {
		isConstructingSnapLine = YES;
		lastPoint = [self closestCornerPoint:[touch locationInView:self]];
	} else {
		lastPoint = [touch locationInView:self];
		[map modifyTilePath:lastPoint atPoint:[self convertCoordsToGridCoords:lastPoint] withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
	}
}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UIColor *tempColor = nil;
    NSString *tempSnapColor = nil;
    if ([LoadedImages sharedLoadedImages].eraserActivated) {
        tempColor = [LoadedImages sharedLoadedImages].selectedColor;
        tempSnapColor =[LoadedImages sharedLoadedImages].selectedSnapColor;
        [LoadedImages sharedLoadedImages].selectedColor = [UIColor clearColor];
        [LoadedImages sharedLoadedImages].selectedSnapColor = nil;
    }
	if (snapToGrid && ![LoadedImages sharedLoadedImages].eraserActivated) {
        [LoadedImages sharedLoadedImages].drawingWidth = 6.0;
		if ([self isCloseToCorner:[[touches anyObject] locationInView:self]]) {
            NSString *drawingColorTexturePath = [[LoadedImages sharedLoadedImages].selectedSnapColor lastPathComponent];
            UIColor *snapColor = [UIColor colorWithPatternImage:[UIImage imageNamed:drawingColorTexturePath]];
			currentPoint = [self closestCornerPoint:[[touches anyObject] locationInView:self]];
			while (currentPoint.x - lastPoint.x > tileSize.width) {
				currentPoint.x = currentPoint.x - tileSize.width;
			}
			while (currentPoint.x - lastPoint.x < -(tileSize.width)) {
				currentPoint.x = currentPoint.x + tileSize.width;
			}
			while (currentPoint.y - lastPoint.y > tileSize.height) {
				currentPoint.y = currentPoint.y - tileSize.height;
			}
			while (currentPoint.y - lastPoint.y < -(tileSize.height)) {
				currentPoint.y = currentPoint.y + tileSize.height;
			}
			if (!CGPointEqualToPoint(lastPoint, currentPoint) && isConstructingSnapLine) {
				CGPoint gridCoords = [self convertCoordsToGridCoords:lastPoint];
				[map modifyTilePath:lastPoint atPoint:gridCoords withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
                 [map modifyTilePath:currentPoint atPoint:gridCoords withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:lastPoint atPoint:CGPointMake(gridCoords.x - 1, gridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(gridCoords.x - 1, gridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:lastPoint atPoint:CGPointMake(gridCoords.x - 1, gridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(gridCoords.x - 1, gridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:lastPoint atPoint:CGPointMake(gridCoords.x, gridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(gridCoords.x, gridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:snapColor withColorTexturePath:drawingColorTexturePath forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((gridCoords.x - 1) * tileSize.width, (gridCoords.y - 1) * tileSize.height, tileSize.width * 2, tileSize.height * 2)];
				lastPoint = currentPoint;
			}
            [LoadedImages sharedLoadedImages].drawingWidth = 2.0;
		}
	} else {
		UITouch *touch = [touches anyObject];
		lastPoint = [touch previousLocationInView:self];
		currentPoint = [touch locationInView:self];
		CGPoint lastGridCoords = [self convertCoordsToGridCoords:lastPoint];
		CGPoint currentGridCoords = [self convertCoordsToGridCoords:currentPoint];
		
		if (!CGPointEqualToPoint(lastGridCoords, currentGridCoords)) {
			[map modifyTilePath:currentPoint atPoint:lastGridCoords withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[self setNeedsDisplayInRect:CGRectMake(lastGridCoords.x*tileSize.width, lastGridCoords.y*tileSize.height, tileSize.width, tileSize.height)];
			[map modifyTilePath:lastPoint atPoint:currentGridCoords withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
		} 
		if (currentPoint.x - tileSize.width * currentGridCoords.x < [LoadedImages sharedLoadedImages].drawingWidth) {
			[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x - 1, currentGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x - 1, currentGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x - 1) * tileSize.width, (currentGridCoords.y) * tileSize.height, tileSize.width, tileSize.height)];
			if (currentPoint.y - tileSize.height * currentGridCoords.y < [LoadedImages sharedLoadedImages].drawingWidth) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x - 1, currentGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x - 1, currentGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x - 1) * tileSize.width, (currentGridCoords.y - 1) * tileSize.height, tileSize.width, tileSize.height)];
			} else if (tileSize.height - (currentPoint.y - tileSize.height * currentGridCoords.y) < [LoadedImages sharedLoadedImages].drawingWidth) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x - 1, currentGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x - 1, currentGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x - 1) * tileSize.width, (currentGridCoords.y + 1) * tileSize.height, tileSize.width, tileSize.height)];
			}
		} else if (tileSize.width - (currentPoint.x - tileSize.width * currentGridCoords.x) < [LoadedImages sharedLoadedImages].drawingWidth) {
			[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x + 1, currentGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x + 1, currentGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x + 1) * tileSize.width, (currentGridCoords.y) * tileSize.height, tileSize.width, tileSize.height)];
			if (currentPoint.y - tileSize.height * currentGridCoords.y < [LoadedImages sharedLoadedImages].drawingWidth) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x + 1, currentGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x + 1, currentGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x + 1) * tileSize.width, (currentGridCoords.y - 1) * tileSize.height, tileSize.width, tileSize.height)];
			} else if (tileSize.height - (currentPoint.y - tileSize.height * currentGridCoords.y) < [LoadedImages sharedLoadedImages].drawingWidth) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x + 1, currentGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x + 1, currentGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x + 1) * tileSize.width, (currentGridCoords.y + 1) * tileSize.height, tileSize.width, tileSize.height)];
			}
		}
		if (currentPoint.y - tileSize.height * currentGridCoords.y < [LoadedImages sharedLoadedImages].drawingWidth) {
			[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x, currentGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x, currentGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x) * tileSize.width, (currentGridCoords.y - 1) * tileSize.height, tileSize.width, tileSize.height)];
		} else if (tileSize.height - (currentPoint.y - tileSize.height * currentGridCoords.y) < [LoadedImages sharedLoadedImages].drawingWidth) {
			[map modifyTilePath:lastPoint atPoint:CGPointMake(currentGridCoords.x, currentGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[map modifyTilePath:currentPoint atPoint:CGPointMake(currentGridCoords.x, currentGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
			[self setNeedsDisplayInRect:CGRectMake((currentGridCoords.x) * tileSize.width, (currentGridCoords.y + 1) * tileSize.height, tileSize.width, tileSize.height)];
		}
		[map modifyTilePath:currentPoint atPoint:currentGridCoords withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
		
		[self setNeedsDisplayInRect:CGRectMake(currentGridCoords.x*tileSize.width, currentGridCoords.y*tileSize.height, tileSize.width, tileSize.height)];
		
		CGPoint tempGridCoords = lastGridCoords;
		while (!CGPointEqualToPoint(tempGridCoords, currentGridCoords)) {
			int deltaX = (int)(currentGridCoords.x) - (int)(tempGridCoords.x);
			int deltaY = (int)(currentGridCoords.y) - (int)(tempGridCoords.y);
			if (deltaX > 0) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x + 1, tempGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x + 1, tempGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x + 1) * tileSize.width, tempGridCoords.y * tileSize.height, tileSize.width, tileSize.height)];
				if (deltaY > 0) {
					[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x + 1, tempGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x + 1, tempGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x + 1) * tileSize.width, (tempGridCoords.y + 1) * tileSize.height, tileSize.width, tileSize.height)];
				}
				if (deltaY < 0) {
					[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x + 1, tempGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x + 1, tempGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x + 1) * tileSize.width, (tempGridCoords.y - 1) * tileSize.height, tileSize.width, tileSize.height)];
				}
			} 
			if (deltaX < 0) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x - 1, tempGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x - 1, tempGridCoords.y) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x - 1) * tileSize.width, tempGridCoords.y * tileSize.height, tileSize.width, tileSize.height)];
				if (deltaY > 0) {
					[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x - 1, tempGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x - 1, tempGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x - 1) * tileSize.width, (tempGridCoords.y + 1) * tileSize.height, tileSize.width, tileSize.height)];
				}
				if (deltaY < 0) {
					[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x - 1, tempGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x - 1, tempGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
					[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x - 1) * tileSize.width, (tempGridCoords.y - 1) * tileSize.height, tileSize.width, tileSize.height)];
				}
			}
			if (deltaY > 0) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x, tempGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x, tempGridCoords.y + 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x) * tileSize.width, (tempGridCoords.y + 1) * tileSize.height, tileSize.width, tileSize.height)];
			} 
			if (deltaY < 0) {
				[map modifyTilePath:lastPoint atPoint:CGPointMake(tempGridCoords.x, tempGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[map modifyTilePath:currentPoint atPoint:CGPointMake(tempGridCoords.x, tempGridCoords.y - 1) withLastPoint:lastPoint withTileSize:tileSize withLineWidth:[LoadedImages sharedLoadedImages].drawingWidth withColor:[LoadedImages sharedLoadedImages].selectedColor forLayer:currentLayerIndex shouldCleanUp:[LoadedImages sharedLoadedImages].eraserActivated];
				[self setNeedsDisplayInRect:CGRectMake((tempGridCoords.x) * tileSize.width, (tempGridCoords.y - 1) * tileSize.height, tileSize.width, tileSize.height)];
			}
			if (abs(deltaX) > abs(deltaY)) {
				if (deltaX > 0) {
					tempGridCoords.x++;
				} else if (deltaX < 0) {
					tempGridCoords.x--;
				}
			} else {
				if (deltaY > 0) {
					tempGridCoords.y++;
				} else if (deltaY < 0) {
					tempGridCoords.y--;
				}
			}
		}
	}
    if ([LoadedImages sharedLoadedImages].eraserActivated && tempColor && tempSnapColor) {
        [LoadedImages sharedLoadedImages].selectedColor = tempColor;
        [LoadedImages sharedLoadedImages].selectedSnapColor = tempSnapColor;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	if (snapToGrid) {
		isConstructingSnapLine = NO;
		[map submitChangesToTiles:[LoadedImages sharedLoadedImages].eraserActivated];
	} else {
		[map submitChangesToTiles:[LoadedImages sharedLoadedImages].eraserActivated];
	}
}

- (CGPoint)convertCoordsToGridCoords:(CGPoint)coords {
	uint x;
	uint y;
	x = (uint)coords.x / (uint)tileSize.width;
	y = (uint)coords.y / (uint)tileSize.height;
	return CGPointMake(x, y);
}

- (BOOL)isCloseToCorner:(CGPoint)point {
	CGPoint gridCoords = [self convertCoordsToGridCoords:point];
	float testPointX = point.x - (gridCoords.x * tileSize.width);
	float testPointY = point.y - (gridCoords.y * tileSize.height);
	if (testPointX < (tileSize.width / 3) && testPointY < (tileSize.height / 3)) {
		return YES;
	} else if (tileSize.width - testPointX < (tileSize.width / 3) && testPointY < (tileSize.height / 3)) {
		return YES;
	} else if (testPointX < (tileSize.width / 3) && tileSize.height - testPointY < (tileSize.height / 3)) {
		return YES;
	} else if (tileSize.width - testPointX < (tileSize.width / 3) && tileSize.height - testPointY < (tileSize.height / 3)) {
		return YES;
	} else {
		return NO;
	}
}

- (CGPoint)closestCornerPoint:(CGPoint)point {
	uint x = (round(point.x / tileSize.width)) * tileSize.width;
	uint y = (round(point.y / tileSize.height)) * tileSize.height;
	return CGPointMake(x, y);
}

@end

